
#include "libmri.h"
#include "auxfns.h"

#include <iostream>
using std::cout;
using std::cerr;
using std::endl;

int main (int argc, char **argv)
{
	if (0 == fftwf_init_threads())
		cerr << "[" << __FILE__ << ": " << __LINE__ << "] "
			<< "fftwf_init_threads() failure!" << endl;	

	/* First things first -- take care of setting up input/output */

	shm_array_t *shm_input, *shm_data;

	if (argc < 2){
		cerr << "Must supply at least 1 argument!" <<
		endl << "> $ " << argv[0] << " input_shm [options ...]" <<
		endl << " or " << argv[0] << " help" << endl;
		return -1;
	}


	bool in_place = false;
	char *p, *input = strdup(argv[1]);
	--argc; ++argv;

	
	if ((p = strrchr (input, '.')) and !strcmp (p+1, "inplace")){
		in_place = true;
		*p = 0;
	}

	if (get_shm_array (input, &shm_input)){
		char buf[1024];
		sprintf (buf, "shm input \"%s\"", input);
		perror (buf);
		return -1;
	}

	char *output;
	if (in_place){
		output = new char [strlen (input) + 1];
		strcpy (output, input);

		shm_data = shm_input;
	}
	else{
		output = new char [strlen(input) + strlen(".recon" + 1)];
	
		memcpy (output, input, strlen(output));
		strcat (output, ".recon");

		if (make_shm_array (output, shm_input, &shm_data)){
			char buf[1024];
			sprintf (buf, "shm output data \"%s\"", output);
			perror (buf);
			return -1;
		}

		int N = 1;
		for (int i = 0; i < shm_input->ndims; ++i)
			N *= shm_input->dims[i];

		memcpy (shm_data->data.c, shm_input->data.c,
		            N*shm_type_sizes [shm_input->type]);

		put_shm_array (input, shm_input);
	}
	free (input);


	int ds0 = shm_data->dims[0],
	    ds1 = shm_data->dims[1],
	    ds2 = shm_data->dims[2],
	    ds3 = shm_data->dims[3];

	int dsize[4] = {ds0, ds1, ds2, ds3};

	cplxf *data = (cplxf*) shm_data->data.c;

	/* OK we have our input/output. Configure from the cmdline */

	l1spirit_config config;
	parse_l1spirit_args (config, argc, argv);

	/* Go! */

	l1spirit (data, dsize, config);

	/* Clean up a little bit (despite being at the end of main) */
	put_shm_array (output, shm_data);
	delete [] output;

	return 0;
}
